package com.offices.subscribe.utils;



import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
public class HttpClientUtil {

    private static PoolingHttpClientConnectionManager connectionManager = null;
    private static HttpClientBuilder httpBuilder = null;
    private static RequestConfig requestConfig = null;
    private static int MAXCONNECTION = 10;
    private static int DEFAULTMAXCONNECTION = 5;
    private static String IP = "https://api.weixin.qq.com";
    private static int status_ok= 200;

    /**
     *@ClassName HttpClientUtil
     *Description: 初始化http工厂对象
     *
     * @param null
     *@Return:
     *@Author:作者
     *@Date:2020/04/28 17:01
    */
    static {
        //设置http的状态参数
        requestConfig = RequestConfig.custom()
                .setSocketTimeout(5000)
                .setConnectTimeout(5000)
                .setConnectionRequestTimeout(5000)
                .build();

        HttpHost target = new HttpHost(IP);
        connectionManager = new PoolingHttpClientConnectionManager();
        //客户端总并行链接最大数
        connectionManager.setMaxTotal(MAXCONNECTION);
        //每个主机的最大并行链接数
        connectionManager.setDefaultMaxPerRoute(DEFAULTMAXCONNECTION);
        connectionManager.setMaxPerRoute(new HttpRoute(target), 20);
        //获得http工厂
        httpBuilder = HttpClients.custom()
                .setConnectionManager(connectionManager);
    }

    /**
     *@ClassName HttpClientUtil
     *Description: 通过http工厂获得可关闭的Http客户端
     *
     *@Return:org.apache.http.impl.client.CloseableHttpClient
     *@Author:作者
     *@Date:2020/04/28 17:04
     */
    public static CloseableHttpClient getConnection() {
        //通过http工厂获得Http客户端
        CloseableHttpClient httpClient = httpBuilder.build();
        return httpClient;
    }
    /**
     *@ClassName HttpClientUtil
     *Description: 拼接参数
     *
     * @param parmMaps
     *@Return:java.util.List<org.apache.http.NameValuePair>
     *@Author:作者
     *@Date:2020/04/28 17:03
     */
    private static List<NameValuePair> concatParms(Map<String, String> parmMaps) {
        List<NameValuePair> paramList = new ArrayList<>();
//        参数流,拼接参数
        parmMaps.entrySet()
                .stream()
                .forEach(entry -> {
                    paramList.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                });
        return paramList;
    }

    /**
     * @method  doRequest
     * @description 执行网络请求
     * @date: 2020/4/28 20:32
     * @author:
     * @param url
     * @param method
     * @param parmMaps
     * @return com.alibaba.fastjson.JSONObject
     */
    public static JSONObject doRequest(String url, HttpRequestMethod requestMethod, Map parmMaps)  {

        JSONObject responseJson = null;
        //得到请求方法实例
        RequestBuilder requestBuilder = RequestBuilder.create(requestMethod.getMethod())
//                添加请求url
                .setUri(url)
                .setConfig(requestConfig);
        HttpUriRequest reqMethod;
//            是get请求就直接添加参数
        if (requestMethod == HttpRequestMethod.GET) {
            //请求参数封装
            List<NameValuePair> params = concatParms(parmMaps);
            reqMethod = requestBuilder.addParameters(params.toArray(new BasicNameValuePair[params.size()]))
                    .build();
        } else {
            // 使用URL实体请求数据转换工具
            StringEntity stringEntity = new StringEntity(JSON.toJSONString(parmMaps),HttpRequestMethod.UTF8_ENCODE.getMethod());
            stringEntity.setContentEncoding(HttpRequestMethod.UTF8_ENCODE.getMethod());
            stringEntity.setContentType(HttpRequestMethod.APPLICATION_JSON.getMethod());
//            UrlEncodedFormEntity entityParam = new UrlEncodedFormEntity(params, "UTF-8");
            reqMethod = requestBuilder.setEntity(stringEntity)
                    .build();
        }

        //获得请求客户端，并相应的请求方法发起请求
        HttpResponse response = null;
        try {

            response = getConnection()
                    .execute(reqMethod);

            //返回的响应实例状态码为200则成功
            if (response.getStatusLine().getStatusCode() == status_ok) {
                //获得响应实体
                HttpEntity entity = response.getEntity();
                //将响应实体转为字符串
                responseJson = JSON.parseObject(EntityUtils.toString(entity, "utf-8"));

            } else {
                log.warn("请求失败");
            }

        } catch (IOException e) {
            e.printStackTrace();
            log.warn("请求失败");
        }

        return responseJson;
    }

}
